/**
 * 
 */
package com.ecp.ws.util;

/**
 * @author jyou
 *
 */

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.dom4j.Attribute;
import org.dom4j.Element;

/**
 * 
 * 类功能描述：2种不同规范格式的xml之间的转换
 *
 * @author 
 * @version 
 * Create:  2012-9-3 下午01:39:16
 */
public class XmlConvertUtils{

	public void xmlToObject(Object obj,Element  element,String packagePath) throws Exception {

        List<Element> elements = element.elements();
        for(Element el:elements){
        	List<Element> subEl = el.elements();    //flights
			setNodeValue(obj, el);
        	boolean one =setAttribute(obj, el);
	        	
				if(subEl.size() > 0){
					List list2 = new ArrayList();
					for(Element el2:subEl){
						String classPath = packagePath+"."+firstToUpperCase(el2.getName());
			        	Object obj2 = Class.forName(classPath).newInstance();
						List<Element> subEl2 = el2.elements();   //flight
						setAttribute(obj2, el2);
						setNodeValue(obj2, el2);
						if(subEl2.size() > 0){
			        		for(Element el3:subEl2){
								List<Element> subEl3 = el3.elements();   //cabins 
								if(subEl3.size() >0){
									List list3 = new ArrayList();
									for(Element el4 :subEl3){
										String classPath2 = packagePath+"."+firstToUpperCase(el4.getName());
							        	Object obj4 = Class.forName(classPath2).newInstance();
										setAttribute(obj4, el4);
										setNodeValue(obj4, el);
										list3.add(obj4);
									}
			        				this.invokeMethod(this.setMethodName(el3.getName()), obj2, list3);
								}
			        		}
		        		}
						list2.add(obj2);
					}
					this.invokeMethod(this.setMethodName(el.getName()), obj, list2);
				}else{
					if(one){
						String classPath = packagePath+"."+el.getName();
			        	Object objOne = Class.forName(classPath).newInstance();
						setAttribute(objOne, el);
						this.invokeMethod(this.setMethodName(el.getName()), obj, objOne);
					}
				}
        }
	}

	/**
	 * @function:设置节点值
	 * @param obj  要初始化的bean
	 * @param element   文档元素
	 * @throws Exception
	 */
	private void setNodeValue(Object obj,Element element) throws Exception{

		String attributeName = element.getName();
		String value = null;
		value = element.getText();
		if(StringUtils.isNotBlank(value)){
			this.invokeMethod(this.setMethodName(attributeName), obj, value);
		}
		

	}
	
		/**
	 * @function:设置节点的属性
	 * @param obj  要初始化的bean
	 * @param element   文档元素
	 * @throws Exception
	 */
	private boolean setAttribute(Object obj,Element element) throws Exception{
		boolean ishasAttr = false;
		for(Iterator it=element.attributeIterator();it.hasNext();){//遍历当前节点的所有属性
			ishasAttr = true;
			Attribute attribute = (Attribute) it.next();
			Field[] field = obj.getClass().getDeclaredFields();
			for (int i=0;i<field.length;i++){  //根据xml内容赋值到对象中，使用对象中默认值不需要重新赋值
				if (field[i].getName().equals(attribute.getName())){
//					System.out.print(" "+field[i].getName());
					this.invokeMethod(this.setMethodName(field[i].getName()), obj, attribute.getText());
				}   
			} 
		}
		return ishasAttr;
//		System.out.println("");
	}
	/**
	 * @function:执行方法
	 * @param methodName 方法名
	 * @param object 方法所在对象
	 * @param value  方法中的参数值
	 */
	private void invokeMethod(String methodName, Object object,String value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {   
		Method method = object.getClass().getMethod(methodName,String.class);
		method.invoke(object,value);
	} 
	
	/**
	 * @function:执行方法
	 * @param methodName 方法名
	 * @param object 方法所在对象
	 * @param value  方法中的参数值
	 */
	private void invokeMethod(String methodName, Object object,Object value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {   
			Method method = object.getClass().getMethod(methodName,value.getClass());
			method.invoke(object,value);
	} 
	
	/**
	 * @function:执行方法
	 * @param methodName 方法名
	 * @param object 方法所在对象
	 * @param value  方法中的参数值
	 */
	private void invokeMethod(String methodName, Object object,List<T> value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {   
		Method method = object.getClass().getMethod(methodName,List.class);
		method.invoke(object,value);
	} 
	
	
	/**
	 * 
	 * @function:执行方法
	 * @param methodName 方法名
	 * @param object 方法所在对象
	 * @return
	 */
	private Object invokeMethod(String methodName, Object object) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {   
		Method method = object.getClass().getMethod(methodName);
		return method.invoke(object);
	} 
	
	/**
	 * 
	 * @function:获得属性值
	 * @param field   属性对象
	 * @param object  属性所属类对象
	 * @return
	 */
	private Object getField(Field field,Object object) throws IllegalArgumentException, IllegalAccessException {   
		field.setAccessible(true);//设置属性可以修改   
		return field.get(object);
	} 
	
	/**
	 * 
	 * @function:通过属性生成get方法名
	 * @param str
	 * @return
	 */
	private String getMethodName(String str){   
		return "get"+ firstToUpperCase(str);   
	}   
	
	/**
	 * 
	 * @function:通过属性生成set方法名
	 * @param str
	 * @return
	 */
	private String setMethodName(String str){   
		return "set"+ firstToUpperCase(str);   
	}   
	
	/**
	 * 首字母大写
	 */
	private String firstToUpperCase(String str){   
		char[] cs=str.toCharArray();
        cs[0]-=32;
        return String.valueOf(cs);
	}
}
